﻿#include "RedisClient.h"

// 获取单例实例
RedisClient& RedisClient::getInstance() {
    static RedisClient instance;
    return instance;
}

// 构造函数：初始化 Redis 连接
RedisClient::RedisClient() {
    try {
        // KV 连接配置
        sw::redis::ConnectionOptions opts;
        opts.host = "127.0.0.1";
        opts.port = 6379;
        opts.socket_timeout = std::chrono::seconds(2); // KV 命令可短超时

        sw::redis::ConnectionPoolOptions pool_opts;
        pool_opts.size = 8;
        pool_opts.wait_timeout = std::chrono::milliseconds(100);
        pool_opts.connection_lifetime = std::chrono::minutes(10);

        _redis = std::make_unique<sw::redis::Redis>(opts, pool_opts);

        // 订阅连接（独立连接，长阻塞）
        sw::redis::ConnectionOptions sub_opts = opts;
        sub_opts.socket_timeout = std::chrono::seconds(0); // 无限阻塞
        _subRedis = std::make_unique<sw::redis::Redis>(sub_opts);
        _subscriber = std::make_unique<sw::redis::Subscriber>(_subRedis->subscriber());

        std::cout << "Redis connected!" << std::endl;
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis init failed: " << e.what() << std::endl;
    }
}

RedisClient::~RedisClient() = default;

// 设置键值
bool RedisClient::set(const std::string& key, const std::string& value, int ttl) {
    try {
        if (ttl > 0) {
            _redis->set(key, value, std::chrono::seconds(ttl));
        } else {
            _redis->set(key, value);
        }
        return true;
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis SET error: " << e.what() << std::endl;
        return false;
    }
}

// 获取值
std::optional<std::string> RedisClient::get(const std::string& key) {
    try {
        auto val = _redis->get(key);  // sw::redis::OptionalString
        return val ? std::optional<std::string>(*val) : std::nullopt;
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis GET error: " << e.what() << std::endl;
        return std::nullopt;
    }
}

// 删除键
bool RedisClient::del(const std::string& key) {
    try {
        return _redis->del(key) > 0;
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis DEL error: " << e.what() << std::endl;
        return false;
    }
}

// LPUSH
void RedisClient::lpush(const std::string& list, const std::string& value) {
    try {
        _redis->lpush(list, value);
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis LPUSH error: " << e.what() << std::endl;
    }
}

// RPOP
std::optional<std::string> RedisClient::rpop(const std::string& list) {
    try {
        auto val = _redis->rpop(list);
        return val ? std::optional<std::string>(*val) : std::nullopt;
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis RPOP error: " << e.what() << std::endl;
        return std::nullopt;
    }
}

// 发布消息
bool RedisClient::publish(const std::string& channel, const std::string& message) {
    try {
        _redis->publish(channel, message);
        return true;
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis PUBLISH error: " << e.what() << std::endl;
        return false;
    }
}

// 订阅消息
void RedisClient::subscribe(const std::string& channel, std::function<void(const std::string&)> callback) {
    try {
        _subscriber->subscribe(channel);

        _subscriber->on_message([callback](std::string, std::string msg) {
            if (callback) {
                callback(msg);
            }
        });

        // 独立线程无限阻塞监听消息
        std::thread([this]() {
            try {
                while (true) {
                    _subscriber->consume();
                }
            } catch (const sw::redis::Error &e) {
                std::cerr << "Redis SUBSCRIBE error: " << e.what() << std::endl;
            }
        }).detach();

        std::cout << "Subscribed to channel: " << channel << std::endl;
    } catch (const sw::redis::Error &e) {
        std::cerr << "Redis SUBSCRIBE setup error: " << e.what() << std::endl;
    }
}
